www.gusucode.com > Matlab在化学工程中的应用 > Matlab在化学工程中的应用/实用化工计算机模拟-Matlab在化学工程中的应用/Examples/Chapter 7/KineticsEst5.m

    function KineticsEst5
% 动力学ODE方程模型的参数估计
%
%   Author: HUANG Huajiang
%   Copyright 2003 UNILAB Research Center, 
%   East China University of Science and Technology, Shanghai, PRC
%   $Revision: 1.0 $  $Date: 2003/06/06 $
%
% [Ref]:Frerich Keil, et al. ed., Scientific computing in chemical 
%   engineering II,1999 (P.351)
%
%   The variables  y here are y(1)=x1, y(2)=x4, y(3)=x5,y(4)=x6 . 

clear all
clc

k0 = [0.5  0.5  0.5  0.5  0.5];         % 参数初值
lb = [0  0  0  0  0];                   % 参数下限
ub = [+inf  +inf  +inf  +inf  +inf];    % 参数上限
x0 = [0.1883  0.2507  0.0467  0.0899  0.1804  0.1394  0.1046];
KineticsData1;
yexp = ExpData(:,2:5);                  % yexp: 实验数据[x1	x4	x5	x6]

% 使用函数fmincon()进行参数估计
[k,fval,flag] = fmincon(@ObjFunc4Fmincon,k0,[],[],[],[],lb,ub,[],[],x0,yexp);
fprintf('\n使用函数fmincon()估计得到的参数值为:\n')
fprintf('\tk1 = %.4f\n',k(1))
fprintf('\tk2 = %.4f\n',k(2))
fprintf('\tk3 = %.4f\n',k(3))
fprintf('\tk4 = %.4f\n',k(4))
fprintf('\tk5 = %.4f\n',k(5))
fprintf('  The sum of the squares is: %.1e\n\n',fval)
k_fmincon = k;

% 使用函数lsqnonlin()进行参数估计
[k,resnorm,residual,exitflag,output,lambda,jacobian] = ...
    lsqnonlin(@ObjFunc4LNL,k0,lb,ub,[],x0,yexp);       
ci = nlparci(k,residual,jacobian);
fprintf('\n\n使用函数lsqnonlin()估计得到的参数值为:\n')
Output

% 以函数fmincon()估计得到的结果为初值,使用函数lsqnonlin()进行参数估计
k0 = k_fmincon;
[k,resnorm,residual,exitflag,output,lambda,jacobian] = ...
    lsqnonlin(@ObjFunc4LNL,k0,lb,ub,[],x0,yexp);       
ci = nlparci(k,residual,jacobian);
fprintf('\n\n以fmincon()的结果为初值,使用函数lsqnonlin()估计得到的参数值为:\n')
Output


% ------------------------------------------------------------------
function f = ObjFunc4Fmincon(k,x0,yexp)
tspan = [0.00 : 0.01 : 0.20];
[t x] = ode45(@KineticEqs,tspan,x0,[],k);   
y(:,1) = x(:,1);
y(:,2:4) = x(:,4:6);
f = sum((y(:,1)-yexp(:,1)).^2) + sum((y(:,2)-yexp(:,2)).^2)   ...
    + sum((y(:,3)-yexp(:,3)).^2) + sum((y(:,4)-yexp(:,4)).^2);

% ------------------------------------------------------------------
function f = ObjFunc4LNL(k,x0,yexp)
tspan = [0.00 : 0.01 : 0.20]; 
[t x] = ode45(@KineticEqs,tspan,x0,[],k);   
y(:,1) = x(:,1);
y(:,2:4) = x(:,4:6);
f1 = y(:,1) - yexp(:,1); 
f2 = y(:,2) - yexp(:,2);
f3 = y(:,3) - yexp(:,3);
f4 = y(:,4) - yexp(:,4);
f = [f1; f2; f3; f4];

% ------------------------------------------------------------------
function dxdt = KineticEqs(t,x,k)
q = 8.75 + k(5);
dxdt =  ...
 [ ( k(5)-q*x(1)- k(1)*x(1)*x(2)-k(4)*x(1)*x(6)*sqrt(0.9) ) 
   ( 7.0-q*x(2) - k(1)*x(1)*x(2)-2*k(2)*x(2)*x(3) )
   ( 1.75 -q*x(3) - k(2)*x(2)*x(3) )
   ( -q*x(4) + 2*k(1)*x(1)*x(2)-k(3)*x(4)*x(5) )
   ( -q*x(5) + 3*k(2)*x(2)*x(3)-k(3)*x(4)*x(5) )
   ( -q*x(6) + 2*k(3)*x(4)*x(5)-k(4)*x(1)*x(6)*sqrt(0.9) )
   ( -q*x(7) + 2*k(4)*x(1)*x(6)*sqrt(0.9) )
];